#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this -> setWindowTitle("围五");
}

MainWindow::~MainWindow()
{
    delete ui;
    delete scene;
    delete view;
    for(int k = 0 ; k < boardWidthSize ; k++){
        for(int j = 0; j < boardHeightSize ; j++){
            delete [] board[k][j];
            delete[] piece[k][j];
        }
        delete [] board[k];
        delete[] piece[k];
    }
    delete[] board;
    delete[] piece;
    for(int i = 0 ; i <= totalPlayer ; i++){
        delete[] Qi[i];
    }
    delete[] Qi;
    delete[] gradient;
    delete[] color;
    delete winner;
    delete winWay;
    delete winLayout;
}
void MainWindow::initBoard(){
    // qDebug() <<"Before board constracting:" << Qt::endl;
    // qDebug() << "PlayerNumberBoxValue now is: " << totalPlayer << Qt::endl;
    // qDebug() << "BoardWidthSizeBoxValue now is: " << boardHeightSize << Qt::endl;
    // qDebug() << "BoardHeightSizeBoxValue now is: " << boardWidthSize << Qt::endl;
    retHorizontal = false;
    retVertical = false;
    retSlantLeft = false;
    retSlantRight = false;
    board = new int**[boardWidthSize];
    piece = new QGraphicsEllipseItem**[boardWidthSize];
    winWay = new QLabel(QString("Win in the way of %1").arg(""));
    winLayout = new QVBoxLayout;
    for(int k = 0 ; k < boardWidthSize ; k++){
        board[k] = new int * [boardHeightSize];
        piece[k] = new QGraphicsEllipseItem * [boardHeightSize];
        for(int i = 0 ; i < boardHeightSize ; i++){
            piece[k][i] = new QGraphicsEllipseItem(k * CELL_SIZE - CELL_SIZE / 4 , i * CELL_SIZE - CELL_SIZE / 4 , CELL_SIZE / 2 , CELL_SIZE / 2 );
            board[k][i] = new int[3];
            board[k][i][0] = 0;
            board[k][i][1] = 0;
            board[k][i][2] = 0;
        }
    }
    Qi = new int*[totalPlayer + 1];
    gradient = new QRadialGradient[totalPlayer + 1];
    for(int i = 0 ; i < totalPlayer + 1;i++){
        gradient[i].setRadius(1);
        gradient[i].setCenter(1,1);
        Qi[i] = new int[5];
        for(int j = 0; j < 5 ; j++){
            Qi[i][j] = 0;
        }
    }
    this -> showFullScreen();
    this -> setWindowFlag(Qt::FramelessWindowHint);
    scene = new QGraphicsScene(this);
    view = new QGraphicsView(scene,this);
    view -> setRenderHint(QPainter::Antialiasing);
    this ->setCentralWidget(view);
    scene -> setBackgroundBrush(QBrush(QColor(100,100,100)));
    currentPlayer = true;
    // for(int i = 0; i < boardWidthSize ; i++){
    //     for(int j = 0 ; j < boardHeightSize ; j++){

    //     }
    // }
    QPen gridPen(QColor(0,100,0),2);
    for(int i = 0 ; i < boardWidthSize ; i++){
        scene -> addLine(i * CELL_SIZE,0 , i * CELL_SIZE , (boardHeightSize - 1) * CELL_SIZE , gridPen );
    }
    for(int i = 0 ; i < boardHeightSize ; i++){
        scene -> addLine(0,i * CELL_SIZE ,(boardWidthSize - 1) * CELL_SIZE , i * CELL_SIZE , gridPen );
    }
    //scene -> addLine(0,i * CELL_SIZE ,(boardHeightSize - 1) * CELL_SIZE , i * CELL_SIZE , gridPen );

}
void MainWindow::drawPiece(int x , int y , int i){
    //QGraphicsEllipseItem * piece = new QGraphicsEllipseItem(x * CELL_SIZE - CELL_SIZE / 4 , y * CELL_SIZE - CELL_SIZE / 4 , CELL_SIZE / 2 , CELL_SIZE / 2 );
    //gradient[i].setColorAt(0,QColor(30 + 50 * i,30 + 50 * i,30 + 50 * i));
    gradient[i].setColorAt(0,color[i]);
    // gradient[i].setColorAt(1,QColor(50 * i,50 * i,50 * i));
    color[i].setRgb(color[i].red(), color[i].green(), color[i].blue());
    gradient[i].setColorAt(1,color[i]);
    color[i].setRgb(color[i].red(), color[i].green(), color[i].blue());
    //piece[x][y] -> setPen(QPen(QColor(30 + 50 * i,30 + 50 * i,30 + 50 * i),1));
    piece[x][y] -> setPen(QPen(color[i],1));
    gradient[i].setCoordinateMode(QGradient::ObjectBoundingMode);
    QBrush brush(gradient[i]);
    piece[x][y] -> setBrush(brush);
    scene -> addItem(piece[x][y]);
    //delete piece;
}
bool MainWindow::checkWin(int x, int y){

    int player = board[x][y][0];
    int count = 1;
    bool ret = false;
    if(player != 0){
        for(int i = x - 1 ; i > x - condition and i >= 0 and board[i][y][0] == player ; i--){
            count ++;
        }
        for(int i = x + 1 ; i < x + condition and i < boardWidthSize and board[i][y][0] == player ; i++){
            count ++;
            //QMessageBox::information(nullptr , "游戏结束","Player:{%1} 以横向连接获胜");
        }
        if(count >= condition){
            retHorizontal = true;
            winWay -> setText(QString("Win in the way of %1").arg("横向连接"));
        }else{
            count = 1;
            for(int i = y - 1 ; i > y - condition and i >= 0 and board[x][i][0] == player ; i--){
                count ++;
            }
            for(int i = y + 1 ; i < y + condition and i < boardHeightSize and board[x][i][0] == player ; i++){
                count ++;
            }
            if(count >= condition){
                retVertical = true;
                winWay -> setText(QString("Win in the way of %1").arg("纵向连接"));
            }else{
                count = 1;
                for(int i = y - 1 , j = x - 1 ; i > y - condition and j > x - condition and i >= 0 and j >= 0 and board[j][i][0] == player ; i-- , j--){
                    count ++;
                    // qDebug() << "3 below work" << "Player: " << currentPlayer << Qt::endl;
                    // qDebug() << "current count " << count << Qt::endl;
                } //3
                for(int i = y + 1 , j = x + 1 ; i < y + condition and j < x + condition and i < boardHeightSize and j < boardWidthSize and board[j][i][0] == player ; i++ , j++){
                    count ++;
                    // qDebug() << "1 above work" << "Player: " << currentPlayer << Qt::endl;
                    // qDebug() << "current count " << count << Qt::endl;
                } //1
                if(count >= condition){
                    retSlantLeft = true;
                    winWay -> setText(QString("Win in the way of %1").arg("自左上到右下连接"));
                    // qDebug() << "retSlantLeft wort" << Qt::endl;
                }else{
                    count = 1;
                    for(int i = x + 1 , j = y - 1; i < x + condition and j > y - condition and j >= 0 and i < boardWidthSize and board[i][j][0] == player ; i++ , j--){
                        count ++;
                        // qDebug() << "4 below work" << "Player: " << currentPlayer << Qt::endl;
                        // qDebug() << "current count " << count << Qt::endl;
                    }//4
                    for(int i = x - 1 , j =  y + 1; i > x - condition and j < y + condition and i >= 0 and j < boardHeightSize and board[i][j][0] == player ; i-- , j++){
                        count ++;
                        // qDebug() << "2 above work" << "Player: " << currentPlayer << Qt::endl;
                        // qDebug() << "current count " << count << Qt::endl;
                    }
                    if(count >= condition){
                        retSlantRight = true;
                        winWay -> setText(QString("Win in the way of %1").arg("自右上到左下连接"));
                    }//2
                }
            }
        }
        ret = retHorizontal or retVertical or retSlantLeft or retSlantRight;
    }
    return ret;
}
void MainWindow::mousePressEvent(QMouseEvent *event){
    QPointF pos = view -> mapToScene(event -> pos());
    int x = static_cast<int>(pos.x() / CELL_SIZE + 0.5);
    int y = static_cast<int>(pos.y() / CELL_SIZE + 0.5);
    // bool ifHaveQi = false;
    //
    // if(board[x][y][1] != 0){
    //     ifHaveQi = true;
    // }
    //qDebug() << "Pointing at:" << "x = " << x << " y = " << y << "board" << board[x][y];
    if(x >= 0 and x < boardWidthSize and y >= 0 and y < boardHeightSize and board[x][y][0] == 0 and ifSelect /*and ifHaveQi*/){
        board[x][y][0] = currentPlayer;
        drawPiece(x , y , currentPlayer);
        left = board[x-1][y][0];
        right = board[x+1][y][0];
        up = board[x][y+1][0];
        down = board[x][y-1][0];
        if(left != currentPlayer and left != 0){
            countQi(x - 1 , y , left , 1);
            remove(1 , left);
        }
        if(right != currentPlayer and right != 0){
            countQi(x + 1 , y , right , 2);
            remove(2 , right);
        }
        if(up != currentPlayer and up != 0){
            countQi(x , y + 1 , up , 3);
            remove(3 , up);
        }
        if(down != currentPlayer and down != 0){
            countQi( x , y - 1 , down , 4);
            remove(4 , down);
        }
        countQi(x , y , currentPlayer , 0);
        remove(0 , currentPlayer);
        //qDebug() << "left:" << left << "right:" << right << "up:" << up << "down:" << down;
        //qDebug() << "当前子气为" << Qi[currentPlayer];
        if(checkWin(x , y)){
            //scene -> setParent(nullptr);
            winner = new QLabel(QString("Winner is : %1").arg(currentPlayer));
            QPalette winnerColor;
            winnerColor.setColor(QPalette::WindowText,color[currentPlayer]);
            winner -> setPalette(winnerColor);
            winWay -> setPalette(winnerColor);
            winner -> setStyleSheet("QLabel {font-size:30px;}");
            winWay -> setStyleSheet("QLabel {font-size:30px;}");
            winLayout -> addWidget(winner);
            winLayout -> addWidget(winWay);
            //winLayout -> setAlignment(Qt::AlignLeft);
            winWidget = new QWidget();
            //this -> setCentralWidget(winWidget);
            //this -> setPalette(QPalette(QColor(255,255,255)));
            winWidget -> setLayout(winLayout);
            scene -> addWidget(winWidget);
            //QString message = QString("Current Palyer : %1 wins the color is :").arg(currentPlayer).arg();
            //QMessageBox::information(this , "GAME OVER" , message);
            //deleteLater();
            QMessageBox Overmessage;
            Overmessage.setText("游戏结束了。");
            Overmessage.setInformativeText("还要再来一把吗？");
            Overmessage.setIcon(QMessageBox::Information);
            Overmessage.setWindowTitle("确认操作");
            Overmessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
            int ret = Overmessage.exec();
            ifConfirm = false;
            ifSelect = false;
            if(ret == QMessageBox::Yes){
                scene -> clear();
                this -> close();
                emit signalShowAdjust();
            }else{
                scene -> clear();
                this -> close();
                emit signalCloseFormMain();
            }
        }else{
            left = 0;
            right = 0;
            up = 0;
            down = 0;
            if(currentPlayer < totalPlayer){
                currentPlayer++;
            }else{
                currentPlayer = 1;
            }
        }
    }
}
void MainWindow::changeBoardWidthSizeValue(int BoardWidthSize){
    this -> boardWidthSize = BoardWidthSize;
    // qDebug() << "BoardWidthSizeBoxValue received from SIGNAL is: " << BoardWidthSize << Qt::endl;
    // qDebug() << "BoardWidthSizeBoxValue now is: " << this -> boardWidthSize << Qt::endl;
}
void MainWindow::changeBoardHeightSizeValue(int BoardHeightSize){
    this -> boardHeightSize =  BoardHeightSize;
    // qDebug() << "BoardHeightSizeBoxValue received from SIGNAL is: " << BoardHeightSize << Qt::endl;
    // qDebug() << "BoardHeightSizeBoxValue now is: " << this -> boardHeightSize << Qt::endl;
}
void MainWindow::changeTotalPlayerValue(int TotalPlayer){
    this -> totalPlayer = TotalPlayer;
    // qDebug() << "PlayerNumberBoxValue received from SIGNAL is: " << TotalPlayer << Qt::endl;
    // qDebug() << "PlayerNumberBoxValue now is: " << this -> totalPlayer << Qt::endl;
}
void MainWindow::ifConfirmAct(bool ret){
    ifConfirm = ret;
    // qDebug() << "ifConfirm received from SIGNAL is: " << ret << Qt::endl;
    // qDebug() << "PlayerNumberBoxValue now is: " << this -> totalPlayer << Qt::endl;
    // qDebug() << "BoardHeightSizeBoxValue now is: " << this -> boardHeightSize << Qt::endl;
    // qDebug() << "BoardWidthSizeBoxValue now is: " << this -> boardWidthSize << Qt::endl;
    if(ifSelect and ifConfirm){
        initBoard();
    }
}
void MainWindow::countQi(int x , int y , int CurrentPlayer , int towards){
    board[x][y][1] = 0;
    // qDebug() << "CurrentPlayer:" << CurrentPlayer;
    // qDebug() << "towards:" << towards;
    if(board[x][y][0] != 0){
        board[x][y][2] = board[x][y][0];
        if(board[x-1][y][2] == 0 and (board[x-1][y][0] == CurrentPlayer or board[x-1][y][0] == 0)){
            if(x - 1 > 0){
                //qDebug() << "In x-1";
                //board[x-1][y][1] += (board[x-1][y][0] == 0);
                board[x-1][y][2] = board[x-1][y][0];
                //Qi[CurrentPlayer] += board[x-1][y][2];
                Qi[CurrentPlayer][towards] += (board[x-1][y][0] == 0);
                //qDebug() << "Qi[" << CurrentPlayer << "]:" << Qi[CurrentPlayer];
                if(board[x-1][y][0] != 0){
                    this -> countQi(x - 1, y ,board[x-1][y][0] , towards);
                }
            }
        }
        if(board[x+1][y][2] == 0 and (board[x+1][y][0] == CurrentPlayer or board[x+1][y][0] == 0)){
            if(x + 1 < boardWidthSize){
                //board[x+1][y][1] += (board[x+1][y][0] == 0);
                board[x+1][y][2] = board[x+1][y][0];
                //Qi[CurrentPlayer] += board[x+1][y][2];
                Qi[CurrentPlayer][towards] += (board[x+1][y][0] == 0);
                if(board[x+1][y][0] != 0){
                    this -> countQi(x + 1, y , board[x+1][y][0] , towards);
                }
            }
        }
        if(board[x][y+1][2] == 0 and (board[x][y+1][0] == CurrentPlayer or board[x][y+1][0] == 0)){
            if(y + 1 < boardHeightSize){
                //board[x][y+1][1] += (board[x][y+1][0] == 0);
                board[x][y+1][2] = board[x][y+1][0];
                //Qi[CurrentPlayer] += board[x][y+1][2];
                Qi[CurrentPlayer][towards] += (board[x][y+1][0] == 0);
                if(board[x][y+1][0] != 0){
                    this -> countQi(x , y + 1 , board[x][y+1][0] , towards);
                }
            }
        }
        if(board[x][y-1][2] == 0 and (board[x][y-1][0] == CurrentPlayer or board[x][y-1][0] == 0)){
            if(y - 1 > 0){
                //board[x][y-1][1] += (board[x][y-1][0] == 0);
                board[x][y-1][2] = board[x][y-1][0];
                //Qi[CurrentPlayer] += board[x][y-1][2];
                Qi[CurrentPlayer][towards] += (board[x][y-1][0] == 0);
                if(board[x][y-1][0] != 0){
                    this -> countQi(x , y - 1, board[x][y-1][0] , towards);
                }
            }
        }
    }
}
void MainWindow::remove(int k , int CurrentPlayer){
    //qDebug() << "当前子气为" << Qi[CurrentPlayer][k] << "end" << Qt::endl;
    // qDebug() << "In remove:" << "当前子气为" << Qi[CurrentPlayer][k];
    // qDebug() << "In remove:" << "CurrentPlayer为" << CurrentPlayer;
    for(int i = 0 ; i < boardWidthSize;i++){
        for(int j = 0; j < boardHeightSize;j++){
            // if(board[i][j][2] != 0){
            // //     qDebug() << "board[" << i << "][" << j << "][2]:" << board[i][j][2];
            // }/*board[i][j][2] != 0 and */
            if(board[i][j][2] == CurrentPlayer){
                board[i][j][1] = Qi[CurrentPlayer][k];
                // qDebug() << "CurrentPlayer:" << CurrentPlayer << "气为：" << board[i][j][1]/* << "end" << Qt::endl*/;
                if(board[i][j][1] == 0){
                    //qDebug() <<  "删除算法";
                    scene -> removeItem(piece[i][j]);
                    board[i][j][0] = 0;
                    //qDebug() << board[i][j][0];
                }
            }
        }
        // qDebug() << Qt::endl;
    }
    for(int i = 0 ; i < boardWidthSize;i++){
        for(int j = 0; j < boardHeightSize;j++){
            board[i][j][2] = 0;
        }
    }
    for(int  i = 0;i <= totalPlayer;i++){
        for(int  j = 0;j < 5;j++){
            Qi[i][j] = 0;
        }
    }
    // qDebug() << Qt::endl << Qt::endl;
}
void MainWindow::receivedColor(QColor * Color){
    color = new QColor[totalPlayer + 1];
    for(int i = 0 ; i <= totalPlayer ; i++){
        color[i] = Color[i];
    }
    ifSelect = true;
    if(ifSelect and ifConfirm){
        initBoard();
    }
}
void MainWindow::recieveWinCondition(int Condition){
    condition = Condition;
}
